import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:kq_flutter_core_widget/widgets/imageBox/kq_image_box.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_add_numer_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_custom_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_edit_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_edit_more_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_header_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_image_box_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_numer_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_only_numer_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_select_item_view.dart';
import 'package:kq_flutter_tv_widgets/widgets/formItem/kq_switcher_item_view.dart';

import '../kq_checkbox_item_view.dart';
import '../kq_radio_item_view.dart';

/// 控件类型
enum ItemType {
  /// 输入控件 [KqEditItemView]
  ///
  /// 【是否必填】 + 左边标题 + 【左边自定义】 + 右边输入框  + 【右边自定义】 + 【单位】
  edit,

  /// 底部固定高度的输入控件 [KqEditMoreView]
  ///
  /// 【是否必填】 + 左边标题 + 底部输入框
  editBottom,

  /// 选择控件 [KqSelectItemView]
  ///
  /// 【是否必填】 + 左边标题 + 【左边自定义】 + 右侧内容 + 【右边自定义】+ 右侧箭头
  select,

  /// 单选控件 [KqRadioItemView]
  ///
  /// 【是否必填】 + 左边标题 + 右侧单选按钮组
  radio,

  /// 多选控件 [KqCheckBoxItemView]
  ///
  /// 【是否必填】 + 左边标题 + 右侧多选按钮组
  checkbox,

  /// 左选择，右数量控件 [KqAddNumberItemView]
  ///
  /// 左边删除图标 + 【标题】 + 选择原因 + 下拉图标 + 数量减按钮  + 数量输入框 + 数量加按钮
  addNumber,

  /// 右数量控件 [KqOnlyNumberItemView]
  ///
  /// 【是否必填】 + 左边标题 + 数量减按钮  + 数量输入框 + 数量加按钮
  onlyNumber,

  /// 开关 [KqSwitcherItemView]
  ///
  /// 【是否必填】 + 左边标题   + 右侧开关
  switcher,

  /// 头部 [KqHeaderItemView]
  ///
  /// 【是否必填】 + 左边标题
  header,

  /// 图片上传 [KqImageBoxItemView]
  ///
  /// 【是否必填】 + 标题 + 底部图片容器
  imageBox,

  /// 空白 [KqEmptyView]
  ///
  /// 高度20的空行
  empty,

  /// 自定义 [KqCustomItemView]
  ///
  /// 【是否必填】 + 左边标题 + 【右边自定义】
  custom
}

/// 通用表单组件实体类
class KqFormEntity {
  /// 控件类型，用来判断当前属于那种表单控件，不传默认empty
  final ItemType? itemType;

  /// 左边标题
  late String title;

  /// 输入框提示文字
  String? hint;

  /// 右边单位
  String? unit;

  /// 是否展示右边单位
  final bool showUnit;

  /// 是否必填，必填有星号，默认false
  late bool mustInput;

  /// 是否可以编辑，默认true，[editableMask]&[editable] 代表真实的能否编辑
  late bool editable;

  /// 是否可以编辑，默认true，[editableMask]&[editable] 代表真实的能否编辑
  late bool editableMask;

  /// 非编辑模式是否强制显示hint
  final bool forceShowPlaceHolder;

  /// 数量组件是否可以删除，默认true
  late bool removable;

  /// 是否多行输入，默认false
  late bool multiline;

  /// 最大行数
  late int? maxLines;

  /// 最多输入几个字符
  final int? maxCharCount;

  /// 标题样式自定义，为了满足某些特殊场景标题样式不一致
  final TextStyle? titleStyle;

  /// 标题颜色,注意：[titleStyle]优先
  late Color? titleColor;

  /// 内容颜色
  late Color? contentColor;

  /// 单位颜色
  final Color? unitColor;

  /// [KqRadioItemView] 或 [KqCheckBoxItemView] 单选按钮之间的距离，默认8+点击区域16=24
  final double? btnSpacing;

  /// [KqSwitcherItemView]自定义开关按钮大小
  final Size? switcherBtnSize;

  /// 选择控件右边文字单行时，超出处理方式
  final TextOverflow? overflow;

  /// 默认值或实际值，用于显示
  String? valueForShow;

  /// 多个默认值或实际值，用于显示[valuesForShow[0]对应从左到右第一个文本框或输入框的显示值，以此类推，未填值的要传null，不能跳过]
  List<String?>? valuesForShow;

  /// 提交值，用于提交给后端
  String? valueForSubmit;

  /// 多个提交值，用于提交给后端[valuesForSubmit[0]对应从左到右第一个文本框或输入框的提交值，以此类推，未填值的要传null，不能跳过]
  List<String?>? valuesForSubmit;

  /// 自定义的标识符，保留字段
  String? itemId;

  /// 用于提交给后端的字段名，提交时对应[valueForSubmit]
  String? contentKey;

  /// 用于提交给后端的字段名，提交时对应[valuesForSubmit]
  List<String>? contentKeyForChild;

  /// 用于提交给后端的字段名，有时候后端不仅要提交数据id，还要求提交数据名称时，用这个，提交时对应[valueForShow]
  String? contentKeyForShow;

  /// 用于提交给后端的字段名，有时候后端不仅要提交数据id，还要求提交数据名称时，用这个，提交时对应[valuesForShow]
  List<String>? contentKeyForShowChild;

  /// 用于提交给后端的字段名，数字表单控件[KqOnlyNumberItemView]，因此数字使用这个字段，提交时对应[qty]
  String? contentKeyForQty;

  /// 用于提交给后端的字段名，提交时对应[unit]
  String? contentKeyForUnit;

  /// 是否可见，默认可见
  late bool visible;

  /// 是否隐藏下划线
  final bool hideDivider;

  /// 整体背景颜色
  Color? backgroundColor;

  /// 是否隐藏[KqImageBoxItemView]右上角的数量统计"1/8"
  final bool hideImageBoxCountInfo;

  /// 数量控件的最小值，小于这个值都显示这个值
  final num minQty;

  /// [KqOnlyNumberItemView] 加减幅度，默认1，比如[qtyStep]=2,则点击加号，数字+2，点击减号，数字-2
  late num qtyStep;

  /// 数量控件的数量
  num qty;

  /// 是否选中，[KqSwitcherItemView]的值，默认false
  bool checked;

  /// [KqSwitcherItemView] 开关自定义
  Widget? Function(KqFormEntity entity)? switcherBuilder;

  /// 键盘显示类型
  TextInputType? inputType;

  /// 键盘右下角按钮类型
  TextInputAction? textInputAction;

  /// 输入框提交回调
  ValueChanged<String>? onSubmitted;

  /// 输入框是否带清空按钮
  final bool enableClearButton;

  /// 是否显示焦点边框，用于扫码枪判断和显示聚焦效果，默认不显示
  late bool showFocusBorder;

  /// 输入内容限制，建议使用[TextInputFormatUtils]
  List<TextInputFormatter>? inputFormatters;

  /// TextEditingController
  TextEditingController? controller;

  /// 多个输入框的TextEditingController
  List<TextEditingController?>? controllers;

  /// 自定义标题距离右边的距离
  double? titleRightMargin;

  /// 输入控件或选择控件的左侧控件
  Widget Function(KqFormEntity entity)? customLeftView;

  /// 输入控件或选择控件或自定义控件的右侧控件
  Widget Function(KqFormEntity entity)? customRightView;

  /// 自定义控件的底部控件
  Widget Function(KqFormEntity entity)? customBottomView;

  /// 强制使用onTap属性，忽略控件是否处于编辑状态。适用于[KqSelectItemView]
  bool forceOnTap;

  /// 自定义或选择控件点击回调
  Function(KqFormEntity entity)? onTap;

  /// 自定义或选择控件的标题点击回调
  final Function(KqFormEntity entity)? onTitleTap;

  /// 输入变化回调
  ValueChanged<String>? onChanged;

  /// 多个输入框项的输入变化回调
  final Function(String value, int index)? onChangedWidthIndex;

  /// 输入变化回调，延迟500ms回调，适用于[KqEditItemView]
  final Function(KqFormEntity entity, String value)? onMonitor;

  /// 多个输入框项的输入变化回调，延迟500ms回调
  final Function(KqFormEntity entity, String value, int index)?
      onMonitorWidthIndex;

  /// 焦点变化
  final Function(bool hasFocus)? onFocusChanged;

  /// 多个输入框项的焦点变化
  final Function(bool hasFocus, int index)? onFocusChangedWidthIndex;

  /// [KqSwitcherItemView]变化监听
  final ValueChanged<bool>? onCheckedChanged;

  /// 控件状态State对象
  late dynamic widgetState;

  /// type
  late dynamic type;

  /// 自定义内容
  late dynamic custom;

  /// 自定义内容
  late dynamic extraData;

  /// 自定义内容
  late dynamic exited;

  /// 最大数量，适用于 [KqImageBoxItemView] 和 [KqOnlyNumberItemView]
  num? maxQty;

  /// 图片选择显示列数，默认8
  int imageBoxCols;

  /// 图片类型和路径
  List<ImageUrl>? imageUrls;

  /// 垂直边距，不赋值则使用主题配置
  final double? paddingVertical;

  /// 水平边距，不赋值则使用主题配置
  final double? paddingHorizontal;

  /// 自定义统计字数的文本
  final String? counterText;

  /// 单位固定宽度，传了则固定显示这个宽度，不论单位是否为空，适用于[KqAddNumberItemView]
  final double? fixedUnitWidth;

  /// 图片添加按钮点击回调
  final Function(KqFormEntity entity, KqImageBoxState state)? onAddTap;

  /// 图片删除按钮点击回调
  final Function(KqFormEntity entity, ImageUrl imageUrl, int position,
      KqImageBoxState state)? onDeleteTap;

  /// 图片点击回调
  final Function(KqFormEntity entity, ImageUrl imageUrl, int position,
      KqImageBoxState state)? onImageTap;

  /// 单选控件的数据，如果要么默认选中某个，[valueForSubmit] 赋值成选中的 [RadioData]的[itemId]
  final List<RadioData>? radioData;

  /// [KqRadioItemView]单选组件单选点击回调
  final Function(KqFormEntity entity, RadioData radioData)? onRadioChanged;

  /// [KqCheckBoxItemView]即将全部取消拦截，有时候需要至少选择一个，且需要提示用户，如果return false，代表不拦截，return true，代表拦截
  final bool Function()? willUnCheckAll;

  /// [KqCheckBoxItemView]多选控件的数据
  List<CheckBoxData>? checkBoxData;

  /// [KqCheckBoxItemView]变化监听
  final Function(KqFormEntity entity, List<CheckBoxData> checkboxData)?
      onCheckBoxChanged;

  /// [KqAddNumberItemView] 数据变动相关回调
  /// 新建一条数据回调
  final Function(KqFormEntity entity, KqFormQtyEntity entityQty)?
      onAddNumberItem;

  /// 删除一条数据
  final Future<bool> Function(KqFormEntity entity, KqFormQtyEntity entityQty)?
      onRemoveNumberItem;

  /// 数字变化
  final Function(KqFormEntity entity, KqFormQtyEntity entityQty)?
      onNumberQtyChanged;

  /// 自定义输入框
  late Function(KqFormEntity entity, KqFormQtyEntity entityQty)?
      customNumberFiled;

  /// 自定义输入框
  late Function(KqFormEntity entity, KqFormQtyEntity entityQty)?
      customTwoNumberFiled;

  /// 数量选择控件点击回调
  final Function(KqFormEntity entity, KqFormQtyEntity entityQty)? onQtyTap;

  /// 数量选择控件列表长度变化监听
  final Function(KqFormEntity entity, List<KqFormQtyEntity> list)?
      onQtyListChanged;

  /// [KqAddNumberItemView] 最大条数，默认不限制
  final int? numberItemMaxRows;

  /// 头的文本大小，考虑到目前有时候存在多种头的文本大小，所以从统一配置中提出来
  double? headerFontSize;

  /// 输入框对齐方式，默认[textAlign.end]，注意：目前仅对[KqEditItemView] 生效。
  TextAlign? textAlign;

  KqFormEntity(
      {this.itemType = ItemType.empty,
      this.title = '',
      this.hint,
      this.unit,
      this.btnSpacing,
      this.showUnit = false,
      this.mustInput = false,
      this.checked = false,
      this.switcherBuilder,
      this.editable = true,
      this.editableMask = true,
      this.multiline = false,
      this.hideDivider = false,
      this.forceShowPlaceHolder = false,
      this.removable = true,
      this.enableClearButton = false,
      this.visible = true,
      this.paddingVertical,
      this.paddingHorizontal,
      this.fixedUnitWidth,
      this.backgroundColor,
      this.maxCharCount,
      this.controller,
      this.controllers,
      this.hideImageBoxCountInfo = false,
      this.inputType,
      this.textInputAction,
      this.onSubmitted,
      this.maxLines,
      this.minQty = 1,
      this.qty = 1,
      this.qtyStep = 1,
      this.titleStyle,
      this.titleColor,
      this.textAlign,
      this.contentColor,
      this.unitColor,
      this.switcherBtnSize,
      this.overflow,
      this.showFocusBorder = false,
      this.inputFormatters,
      this.valueForShow,
      this.valuesForShow,
      this.valueForSubmit,
      this.valuesForSubmit,
      this.titleRightMargin,
      this.customLeftView,
      this.customRightView,
      this.customBottomView,
      this.forceOnTap = false,
      this.onTap,
      this.onTitleTap,
      this.onFocusChanged,
      this.onFocusChangedWidthIndex,
      this.onChanged,
      this.onChangedWidthIndex,
      this.onAddNumberItem,
      this.onRemoveNumberItem,
      this.onNumberQtyChanged,
      this.onMonitor,
      this.onMonitorWidthIndex,
      this.onQtyTap,
      this.onCheckedChanged,
      this.contentKey,
      this.contentKeyForChild,
      this.contentKeyForQty,
      this.contentKeyForShow,
      this.contentKeyForShowChild,
      this.contentKeyForUnit,
      this.itemId,
      this.checkBoxData,
      this.widgetState,
      this.maxQty,
      this.imageBoxCols = 8,
      this.imageUrls,
      this.custom,
      this.radioData,
      this.onRadioChanged,
      this.onCheckBoxChanged,
      this.willUnCheckAll,
      this.onAddTap,
      this.onDeleteTap,
      this.onImageTap,
      this.numberItemMaxRows,
      this.onQtyListChanged,
      this.extraData,
      this.type,
      this.counterText = '',
      this.customNumberFiled,
      this.customTwoNumberFiled,
      this.headerFontSize,
      this.exited});

  /// 是否真正能编辑
  bool isEditable() {
    return editable && editableMask;
  }

  /// 刷新绑定的控件
  void updateWidget() {
    if (widgetState != null) {
      widgetState.update();
    }
  }
}

//
class KqFormSubEntity {
  /// 左边标题
  late String? title;

  /// 左边标题
  late String? titleId;

  ///展示值
  late String? value;

  /// 右边单位
  final String? unit;

  KqFormSubEntity({this.title, this.titleId, this.value, this.unit});
}

// 数字类型控件实体类
class KqFormQtyEntity {
  /// 显示值
  late String? valueForShow;

  /// 自定义值
  late String? customValue;

  /// 提交值，一般是id
  late String? valueForSubmit;

  /// 选择控件的提示文字
  late String? hint;

  /// 输入框数值
  late num qty;

  /// 输入框最小值
  late num minQty;

  /// 右边单位，非必填
  late String? unit;

  /// 输入框是否为空
  late bool isEmpty;

  /// 是否显示删除按钮
  late bool removable;

  /// 是否可以编辑，默认true，[editableMask]&[editable] 代表真实的能否编辑
  late bool editable;

  /// 是否可以编辑，默认true，[editableMask]&[editable] 代表真实的能否编辑
  late bool editableMask;

  /// 背景颜色
  final Color? backgroundColor;

  /// 数字文字颜色
  final Color? qtyTextColor;

  /// 单位颜色
  final Color? unitColor;

  /// 垂直边距，不赋值则使用主题配置
  final double? paddingVertical;

  /// 水平边距，不赋值则使用主题配置
  final double? paddingHorizontal;

  /// 单位固定宽度，传了则固定显示这个宽度，不论单位是否为空，适用于[KqNumberItemView]
  final double? fixedUnitWidth;

  /// 选择控件点击回调
  late Function(KqFormQtyEntity entity)? onTap;

  /// 数量组件删除按钮点击回调
  late Function(KqFormQtyEntity entity)? onRemove;

  /// 数字变化
  late Function(KqFormQtyEntity entity)? onNumberQtyChanged;

  /// 自定义输入框
  late Function(KqFormQtyEntity entity, String text)? customNumberFiled;

  /// 自定义输入框
  late Function(KqFormQtyEntity entity, String text)? customTwoNumberFiled;

  /// 控件状态State对象
  late dynamic widgetState;

  /// 额外数据，备用
  late dynamic extraData;

  /// 输入内容限制左边输入框
  final List<TextInputFormatter>? inputFormattersTextLeft;

  /// 输入内容限制右边边输入框
  final List<TextInputFormatter>? inputFormattersTextRight;

  /// 自定义值
  late dynamic customNumber;

  ///自定义值
  late dynamic customTwoNumber;

  KqFormQtyEntity(
      {this.valueForShow,
      this.valueForSubmit,
      this.hint,
      this.qty = 1,
      this.minQty = 1,
      this.onTap,
      this.paddingVertical,
      this.paddingHorizontal,
      this.onRemove,
      this.unitColor,
      this.qtyTextColor,
      this.isEmpty = false,
      this.removable = true,
      this.editable = true,
      this.editableMask = true,
      this.fixedUnitWidth,
      this.backgroundColor,
      this.extraData,
      this.onNumberQtyChanged,
      this.unit,
      this.widgetState,
      this.inputFormattersTextLeft,
      this.inputFormattersTextRight,
      this.customNumber,
      this.customTwoNumber,
      this.customNumberFiled,
      this.customTwoNumberFiled,
      this.customValue});

  /// 是否真正能编辑
  bool isEditable() {
    return editable && editableMask;
  }

  /// 刷新绑定的控件
  void updateWidget() {
    if (widgetState != null) {
      widgetState.update();
    }
  }
}

// 最基本的展示
class KqFormBaseEntity {
  /// 显示值
  late String? valueForShow;

  /// 提交值，一般是id
  late String? valueForSubmit;

  ///提交值，一般是数量
  late String? valueForNumber;

  /// 数量组件删除按钮点击回调
  final Function(KqFormBaseEntity entity)? onRemove;

  KqFormBaseEntity({
    this.valueForShow,
    this.valueForSubmit,
    this.onRemove,
    this.valueForNumber,
  });
}

// 附件相关的数据
class KqFromAttachEntity {
  ///附件名称
  late String? attachmentName;

  ///附件名称
  late String? fileName;

  ///点击回调
  final Function(KqFromAttachEntity entity, int index)? onTap;

  KqFromAttachEntity({
    this.attachmentName,
    this.fileName,
    this.onTap,
  });
}
